package com.qijian.plug.capacity.approval;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.qijian.common.annotation.Log;
import com.qijian.common.core.domain.entity.FlowableSuccess;
import com.qijian.common.enums.ApprovalDescriptionEnum;
import com.qijian.common.enums.BusinessType;
import com.qijian.common.utils.DateUtils;
import com.qijian.common.utils.mybatis.WhereEntityTool;
import com.qijian.flowable.domain.Flow;
import com.qijian.flowable.domain.FlowableForm;
import com.qijian.flowable.domain.FlowableRecord;
import com.qijian.flowable.domain.vo.ExecRecordVo;
import com.qijian.flowable.service.IFlowService;
import com.qijian.flowable.service.IFlowableFormService;
import com.qijian.flowable.service.IFlowableRecordService;
import com.qijian.system.service.ISysUserService;
import com.qijian.tool.domain.Msg;
import com.qijian.tool.domain.query.MsgQuery;
import com.qijian.tool.service.IMsgService;
import lombok.RequiredArgsConstructor;
import org.flowable.engine.TaskService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author qijian
 */
@Component
@RequiredArgsConstructor
public class ApprovalSuccess extends ApprovalPlugWrapper<FlowableSuccess.Approval> {

    private final IFlowableRecordService flowableRecordService;
    private final IFlowableFormService flowableFormService;

    private final IMsgService msgService;
    private final TaskService taskService;


    private final IFlowService flowService;


    private final ISysUserService userService;

    private static final int DELETE = 1;
    private static final int INSERT = 2;
    private static final int MODIFY = 3;

    private static final int OLD = 1;
    private static final int NEW = 2;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doSomething(List<Object> args) {
        this.operation(args);
    }

    @Log(title = "流程完成", businessType = BusinessType.APPROVAL)
    protected void operation(List<Object> args) {
        if (CollectionUtil.isNotEmpty(args)) {
            if (args.get(0) instanceof String) {
                // 流程Key
                String processInstanceId = (String) args.get(0);
                String variables = ObjectUtil.isNotNull(args.get(1)) ? (String) args.get(1) : null;
                String nickName = ObjectUtil.isNotNull(args.get(2)) ? (String) args.get(2) : null;
                Long userId = ObjectUtil.isNotNull(args.get(3)) ? (Long) args.get(3) : null;
//                Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
                FlowableRecord record = flowableRecordService.getById(processInstanceId);
                if (ObjectUtil.isNotNull(record) && !ApprovalDescriptionEnum.C.getValue().equals(record.getStatus()) && !ApprovalDescriptionEnum.T.getValue().equals(record.getStatus())) {
                    // 流程业务处理
                    record.setStatus(ApprovalDescriptionEnum.C.getValue());
                    record.setBusinessValues(variables);
                    record.setExecutorId(userId);
                    record.setUpdateBy(nickName);
                    flowableRecordService.updateById(record);

                    // 消息关闭
                    MsgQuery msgQuery = new MsgQuery();
                    msgQuery.setSourceId(processInstanceId);
                    List<Msg> msgList = msgService.list(WhereEntityTool.invoke(msgQuery));
                    if (CollectionUtil.isNotEmpty(msgList)) {
                        msgList.forEach(msg -> {
                            msg.setTitle(null);
                            msg.setContent(null);
                            msg.setIsClose(true);
                            msg.setIsRead(true);
//                            if (userId != null) {
//                                msg.setIsRead(msg.getUserId().compareTo(userId) == 0);
//                            }
                            msg.setUpdateBy(nickName);
                        });
                        msgService.updateBatchById(msgList);
                    }

                    // 解析参数
                    FlowableForm flowableForm = flowableFormService.getById(record.getBusinessKey());
                    if (ObjectUtil.isNotNull(flowableForm)) {
                        JSONArray jsonArray = JSONUtil.parseObj(flowableForm.getFormJson()).getJSONArray("list");
                        JSONObject params = JSONUtil.parseObj(record.getBusinessValues());
                        JSONObject result = new JSONObject();
                        for (int i = 0; i < jsonArray.size(); i++) {
                            String key = jsonArray.getJSONObject(i).getStr("model");
                            String name = jsonArray.getJSONObject(i).getStr("name");
                            if (ObjectUtil.isNotNull(params.getStr(jsonArray.getJSONObject(i).getStr("model")))) {
                                result.set(name, params.getStr(key));
                            }
                        }
                        // 执行业务处理
                        ExecRecordVo vo = new ExecRecordVo();
                        vo.setType(record.getBusinessKey());
                        vo.setJsonStr(result.toString());
                        vo.setProcessInstanceId(processInstanceId);
                        flowableRecordService.execRecord(vo);
                    }

                    if (record.getBusinessKey().startsWith("flow_")) {
                        Flow flow = new Flow();
                        flow.setId(record.getSourceId());
                        flow.setApprovalStatus(ApprovalDescriptionEnum.C);
                        flow.setApprovalBy(nickName);
                        flow.setApprovalTime(DateUtils.getNowDate());
                        flow.setUpdateBy(nickName);
                        flowService.updateById(flow);
                    }
                }
            } else {
                // ID
                Long id = (Long) args.get(0);
                // 流程Key
                String processDefinitionKey = args.get(1).toString();
               if ("bomMaterialPre".equals(processDefinitionKey)) {
//                    preCost(id);
                }
            }
        }
    }

}
